package com.cryptape.cita_wallet.activity.transfer;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.cryptape.cita_wallet.activity.EntrustNewActivity;
import com.cryptape.cita_wallet.bean.DepositData;
import com.cryptape.cita_wallet.bean.MaxDetailBean;
import com.cryptape.cita_wallet.constant.ConstantUtil;
import com.cryptape.cita_wallet.event.TransferPushEvent;
import com.cryptape.cita_wallet.item.Chain;
import com.cryptape.cita_wallet.item.Currency;
import com.cryptape.cita_wallet.item.Token;
import com.cryptape.cita_wallet.item.Wallet;
import com.cryptape.cita_wallet.item.transaction.AppTransaction;
import com.cryptape.cita_wallet.service.ContractService;
import com.cryptape.cita_wallet.service.DepositQueryService;
import com.cryptape.cita_wallet.service.http.CITARpcService;
import com.cryptape.cita_wallet.service.http.CytonSubscriber;
import com.cryptape.cita_wallet.service.http.EthRpcService;
import com.cryptape.cita_wallet.service.http.TokenService;
import com.cryptape.cita_wallet.service.http.WalletService;
import com.cryptape.cita_wallet.util.CurrencyUtil;
import com.cryptape.cita_wallet.util.NumberUtil;
import com.cryptape.cita_wallet.util.db.DBWalletUtil;
import com.cryptape.cita_wallet.util.ether.EtherUtil;
import com.cryptape.cita_wallet.util.url.HttpCITAUrls;
import com.mangoworld.android.R;

import org.greenrobot.eventbus.EventBus;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Numeric;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.Callable;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.cryptape.cita_wallet.activity.transfer.TransferActivity.EXTRA_ADDRESS;
import static com.cryptape.cita_wallet.activity.transfer.TransferActivity.EXTRA_TOKEN;

/**
 * Created by dengming on 11/2/20.
 */

public class EntrustNewTransferPresenter {

    private EntrustNewActivity mActivity;
    private TransferView mTransferView;

    private Token mToken;
    public Token mToken1;
    private double mTokenPrice = 0;
    private Wallet mWallet;
    private Currency mCurrency;

    private BigInteger mGasLimit;
    public BigInteger mGasPrice = new BigInteger("-1");
    private BigInteger mGas;
    private BigInteger mQuota, mQuotaLimit, mQuotaPrice;
    private String mData;
    public double mTokenBalance = -1;
    public double mNativeTokenBalance = -1;
    public double mTransferFee;
    public double mTokenHBalance = -1;
    public final static String TYPE_LOCK_NATURE = "Nature";
    public final static String TYPE_LOCK_MIX = "Mix";
    public final static String TYPE_LOCK_EMPTY = "Empty";
    public MaxDetailBean mBean;
    //    public String mType;
//    private String mLockAddress;
    public final static int TYPE_CURRENT_STEP_TRANSFER = 1;
    public final static int TYPE_CURRENT_STEP_LOCK = 2;
    //    public int mCurrentStep = TYPE_CURRENT_STEP_TRANSFER;
    public DepositData mDepositData = new DepositData();

    public EntrustNewTransferPresenter(EntrustNewActivity activity, TransferView transferView) {
        mActivity = activity;
        mTransferView = transferView;

        init();
    }

    public void init() {
        EthRpcService.init(mActivity);
        CITARpcService.init(mActivity, HttpCITAUrls.CITA_NODE_URL);
        initTokenItem();
        getAddressData();
        initWalletData();
//        getTokenBalance();
        initTransferFee();
        getDepositData();
    }

    private void getDepositData() {
        mActivity.showProgressBar();
        mActivity.dialog.setCancelable(false);
        DepositQueryService.queryDepositData().subscribe(new Subscriber<DepositData>() {
            @Override
            public void onCompleted() {
                mActivity.dismissProgressBar();
//                mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
            }

            @Override
            public void onError(Throwable e) {
                mActivity.dismissProgressBar();
                Toast.makeText(mActivity, mActivity.getString(R.string.get_entrust_data_fail), Toast.LENGTH_SHORT).show();
//                mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
            }

            @Override
            public void onNext(DepositData depositData) {
                mDepositData = depositData;
                if (mDepositData.getCode() != 0) {
                    Toast.makeText(mActivity, R.string.get_entrust_data_fail, Toast.LENGTH_SHORT).show();
                    return;
                }
                mActivity.setLockType(depositData.getType());
//                            mix_queryDetail();
                mActivity.updateLockStatus();
            }
        });
    }

    public BigInteger getmGasLimit() {
//        if (mGasLimit == null) {
//            mGasLimit = ConstantUtil.GAS_ERC20_LIMIT_DEFAULT;
//        }
        return this.mGasLimit;
    }


    private void queryNativeBalance() {
        WalletService.getBalanceWithNativeToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
            @Override
            public void onNext(Double balance) {
                mNativeTokenBalance = balance;
                mTransferView.updateNativeTokenBalance(balance);
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
//                mActivity.dismissProgressCircle();
                Toast.makeText(mActivity, mActivity.getString(R.string.query_balance_fail), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCompleted() {
//                mActivity.dismissProgressCircle();

            }
        });
    }

    private void queryToken2Balnce() {
        mActivity.showProgressBar();
//        if(mToken1 != null)
        {
            WalletService.getBalanceWithToken(mActivity, mToken1).subscribe(new Subscriber<Double>() {
                @Override
                public void onNext(Double balance) {
                    mTokenHBalance = balance;
                    mActivity.updateMixHTokenBalance(balance);
                    mix_queryDetail();
                }

                @Override
                public void onError(Throwable e) {
                    mActivity.dismissProgressBar();

//                    mActivity.dismissProgressCircle();
                    Toast.makeText(mActivity, mActivity.getString(R.string.query_balance_fail), Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onCompleted() {
                    mActivity.dismissProgressBar();
                }
            });
//            mix_queryDetail();
        }
    }

    private void getToken1Balance() {
        WalletService.getBalanceWithToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
            @Override
            public void onNext(Double balance) {
                mTokenBalance = balance;
                mTransferView.updateAnyTokenBalance(balance);
            }

            @Override
            public void onError(Throwable e) {
//                mActivity.dismissProgressCircle();
                Toast.makeText(mActivity, mActivity.getString(R.string.query_balance_fail), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCompleted() {

            }
        });
    }

    public void getTokenBalance() {
//        queryNativeBalance();
        queryNativeBalance();
        getToken1Balance();
        if (mToken1 != null) {
            queryToken2Balnce();
        }
//        mActivity.showProgressCircle();
//        WalletService.getBalanceWithToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
//            @Override
//            public void onNext(Double balance) {
//                mTokenBalance = balance;
//                mTransferView.updateAnyTokenBalance(balance);
//
//                if (mToken1 != null)
//                {
//                    queryToken2Balnce();
//                } else
//                    {
//                    queryNativeBalance();
//                }
//            }
//
//            @Override
//            public void onError(Throwable e) {
//                mActivity.dismissProgressCircle();
//                Toast.makeText(mActivity, mActivity.getString(R.string.query_balance_fail), Toast.LENGTH_SHORT).show();
//            }
//
//            @Override
//            public void onCompleted() {
//
//            }
//        });
//        if(mToken1 != null) {
//            WalletService.getBalanceWithToken(mActivity, mToken1).subscribe(new CytonSubscriber<Double>() {
//                @Override
//                public void onNext(Double balance) {
//                    mTokenHBalance = balance;
//                    mActivity.updateMixHTokenBalance(balance);
//                }
//            });
//            mix_queryDetail();
//        }
//        WalletService.getBalanceWithNativeToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
//            @Override
//            public void onNext(Double balance) {
//                mNativeTokenBalance = balance;
//                mTransferView.updateNativeTokenBalance(balance);
//            }
//
//            @Override
//            public void onError(Throwable e) {
//                e.printStackTrace();
//            }
//
//            @Override
//            public void onCompleted() {
//
//            }
//        });
    }

    private void getAddressData() {
        String address = mActivity.getIntent().getStringExtra(EXTRA_ADDRESS);
        mTransferView.updaterReceiveAddress(address);
    }

    private void initTokenItem() {
        mToken = mActivity.getIntent().getParcelableExtra(EXTRA_TOKEN);
//        mTransferView.updateTitleData("闪电兑换");
    }

    private void initWalletData() {
        mWallet = DBWalletUtil.getCurrentWallet(mActivity);
        mTransferView.updateWalletData(mWallet);
    }

    private void initTransferFee() {
        if (EtherUtil.isEther(mToken)) {
            initEthGasInfo();
            mTransferView.initTransferEditValue();
            initTokenPrice();

        } else {
            initCITAQuota();
        }
//        if (mCurrentStep == EntrustNewTransferPresenter.TYPE_CURRENT_STEP_TRANSFER) {
//            initEthGasLimit(mActivity.getTransferTransaction());
//        } else {
//            initEthGasLimit(mActivity.getLockTransaction());
//        }
    }

    private void initEthGasInfo() {
//        mGasLimit = EtherUtil.isNative(mToken) ? ConstantUtil.QUOTA_TOKEN : ConstantUtil.QUOTA_ERC20;
//        mGasLimit = ConstantUtil.QUOTA_ERC20_BIG;
//        mGasPrice = ConstantUtil.GAS_PRICE_BIG_1;
//        mTransferView.startUpdateEthGasPrice();
        EthRpcService.getEthGasPrice().subscribe(new CytonSubscriber<BigInteger>() {
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                mTransferView.updateEthGasPriceFail(e);
            }

            @Override
            public void onNext(BigInteger gasPrice) {
                if (gasPrice.compareTo(mGasPrice) > 0) {
                    mGasPrice = gasPrice;
                }

                updateGasInfo();
                mTransferView.updateEthGasPriceSuccess(gasPrice);
//                getLockType();
                //开始请求锁仓数据
//                mTransferView.startUpdateEthGasPrice();
//                initDepositData();
//                DepositQueryService.queryDepositData().subscribe(new Subscriber<DepositData>() {
//                    @Override
//                    public void onCompleted() {
//                        mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
//                    }
//
//                    @Override
//                    public void onNext(DepositData depositData) {
//                        mDepositData = depositData;
//                        mActivity.setLockType1(depositData.getType());
//                        if (depositData.getType() !=null && depositData.getType().equals(TYPE_LOCK_MIX)) {
//                            mActivity.setLockType(TYPE_LOCK_MIX);
////                            mix_queryDetail();
//                        }
//                        mActivity.updateLockStatus();
//                    }
//                });
            }
        });
    }

    /**
     * get the price of token
     */
    private void initTokenPrice() {
        mCurrency = CurrencyUtil.getCurrencyItem(mActivity);
        TokenService.getCurrency(ConstantUtil.ETH, mCurrency.getName())
                .subscribe(new CytonSubscriber<String>() {
                    @Override
                    public void onNext(String price) {
                        if (TextUtils.isEmpty(price))
                            return;
                        try {
                            mTokenPrice = Double.parseDouble(price);
                            mTransferView.initTransferFeeView();
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                    }
                });
    }


    private void initCITAQuota() {
        mQuotaLimit = TextUtils.isEmpty(getTokenItem().getContractAddress()) ? ConstantUtil.QUOTA_TOKEN : ConstantUtil.QUOTA_ERC20;
        CITARpcService.getQuotaPrice(mWallet.address)
                .subscribe(new CytonSubscriber<String>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(String quotaPrice) {
                        mQuotaPrice = new BigInteger(quotaPrice);
                        initQuotaFee();
                        mTransferView.initTransferFeeView();
                    }
                });

    }

    private void initQuotaFee() {
        mQuota = mQuotaLimit.multiply(mQuotaPrice);
        mTransferFee = NumberUtil.getEthFromWei(mQuota);
        mTransferView.updateCITAQuota(NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit());
    }

    public void updateQuotaLimit(BigInteger quotaLimit) {
        mQuotaLimit = quotaLimit;
        initQuotaFee();
    }

    public BigInteger getQuotaLimit() {
        return mQuotaLimit;
    }

    public void initEthGasLimit(Transaction transaction) {
        EthRpcService.getEthGasLimit(transaction)
                .subscribe(new CytonSubscriber<BigInteger>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        Log.e("MainActivity", "getEthGasLimit:" + e.getMessage());
//                        mTransferView.transferEtherFail("");
                    }

                    @Override
                    public void onNext(BigInteger gasLimit) {
                        Log.e("MainActivity", "getEthGasLimit:" + (gasLimit == null ? "" : gasLimit.toString()));
                        if (gasLimit == null) {
                            if (mDepositData.getStep() == TYPE_CURRENT_STEP_LOCK) {
                                if (mDepositData.isAppend()) {
                                    mGasLimit = ConstantUtil.QUOTA_ERC20_BIG_APPEND;
                                } else {
                                    mGasLimit = ConstantUtil.QUOTA_ERC20_BIG;
                                }
                            } else if (mDepositData.getStep() == TYPE_CURRENT_STEP_TRANSFER) {
                                mGasLimit = ConstantUtil.GAS_ERC20_LIMIT_DEFAULT;
                            }
                        } else {
                            BigInteger newGasLimit = new BigDecimal(gasLimit).multiply(new BigDecimal("1.1")).toBigInteger();
//                            if (mGasLimit == null || mGasLimit == ConstantUtil.GAS_ERC20_LIMIT_DEFAULT || newGasLimit.compareTo(getmGasLimit()) > 0)
                            if (mDepositData.getStep() == TYPE_CURRENT_STEP_TRANSFER) {
                                if (mGasLimit != null && mGasLimit.compareTo(ConstantUtil.GAS_ERC20_LIMIT_DEFAULT) != 0
                                        && newGasLimit.compareTo(mGasLimit) < 0) {

//                                    mGasLimit = newGasLimit;
                                } else {
                                    mGasLimit = newGasLimit;
                                }
                            } else {
                                mGasLimit = newGasLimit;
                            }
//                            mGasLimit = new BigDecimal(gasLimit).multiply(new BigDecimal("1.1")).toBigInteger();
                        }
                        updateGasInfo();
                    }
                });
    }

    public void initGasLimit(AppTransaction appTransaction) {
        EthRpcService.getEthGasLimit(appTransaction)
                .subscribe(new CytonSubscriber<BigInteger>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(BigInteger gasLimit) {
                        mGasLimit = gasLimit.multiply(ConstantUtil.GAS_LIMIT_PARAMETER);
                        updateGasInfo();
                    }
                });
    }

    public void handleEntrustTransferAction(String password, String transferValue, String receiveAddress, String type) {
        if (EtherUtil.isEther(mToken)) {
            if (ConstantUtil.ETH.equals(mToken.getSymbol())) {
                transferEth(password, transferValue, receiveAddress);
            } else {
                transferEntrustEthErc20(password, transferValue, receiveAddress, type);
            }
        }
    }

    private void transferEth(String password, String value, String receiveAddress) {
        EthRpcService.transferEth(mActivity, receiveAddress, value, mGasPrice, mGasLimit, mData, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferCITAFail(e);
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        Log.e("MainActivity", ethSendTransaction.getTransactionHash());
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                        }
                    }
                });
    }

    private void lockSingle(String password, String value, String receiveAddress, String type) {
        switch (type) {
            case TYPE_LOCK_NATURE:
                EthRpcService.lockNature(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                        .subscribe(new CytonSubscriber<EthSendTransaction>() {
                            @Override
                            public void onError(Throwable e) {
                                mTransferView.transferEtherFail(e.getMessage());
                            }

                            @Override
                            public void onNext(EthSendTransaction ethSendTransaction) {
                                if (ethSendTransaction.hasError()) {
                                    mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                                } else {
                                    mTransferView.transferEtherSuccess(ethSendTransaction);
                                    EventBus.getDefault().post(new TransferPushEvent());
                                    mActivity.finish();
                                }
                            }
                        });
                break;
            case TYPE_LOCK_EMPTY:
                EthRpcService.lockEmpty(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                        .subscribe(new CytonSubscriber<EthSendTransaction>() {
                            @Override
                            public void onError(Throwable e) {
                                mTransferView.transferEtherFail(e.getMessage());
                            }

                            @Override
                            public void onNext(EthSendTransaction ethSendTransaction) {
                                if (ethSendTransaction.hasError()) {
                                    mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                                } else {
                                    mTransferView.transferEtherSuccess(ethSendTransaction);
                                    EventBus.getDefault().post(new TransferPushEvent());
                                    mActivity.finish();
                                }
                            }
                        });

                break;
        }
    }

    public void handleMixLock(String password, String value, String receiveAddress) {
        if (mDepositData.isAppend()) {
            if (mGasLimit == null || mGasLimit.compareTo(BigInteger.ZERO) == 0) {
                mGasLimit = ConstantUtil.QUOTA_ERC20_BIG_APPEND;
            }
            lock_mix_append(password, value, receiveAddress);
        } else {
            if (mGasLimit == null || mGasLimit.compareTo(BigInteger.ZERO) == 0) {
                mGasLimit = ConstantUtil.QUOTA_ERC20_BIG;
            }
            exec_Lock_MixNew(mActivity, getTokenItem(), receiveAddress, value, mGasPrice, getmGasLimit(), password);
        }
    }

    private void lock_mix_append(String password, String value, String receiveAddress) {
        EthRpcService.lockMixAppend(mActivity, mToken, receiveAddress, value, mGasPrice, getmGasLimit(), password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                            EventBus.getDefault().post(new TransferPushEvent());
                            mActivity.finish();
                        }
                    }
                });
    }

    private void lockAppend(String password, String value, String receiveAddress) {
        EthRpcService.lockAppend(mActivity, mToken, receiveAddress, value, mGasPrice, getmGasLimit(), password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                            EventBus.getDefault().post(new TransferPushEvent());
                            mActivity.finish();
                        }
                    }
                });
    }

    public void handleLock(String password, String value, String receiveAddress, String type) {
        if (mDepositData.isAppend()) {
            if (mGasLimit == null || mGasLimit.compareTo(BigInteger.ZERO) == 0) {
                mGasLimit = ConstantUtil.QUOTA_ERC20_BIG_APPEND;
            }
            lockAppend(password, value, mDepositData.getLockAddress());
        } else {
            if (mGasLimit == null || mGasLimit.compareTo(BigInteger.ZERO) == 0) {
                mGasLimit = ConstantUtil.QUOTA_ERC20_BIG;
            }
            lockSingle(password, value, receiveAddress, type);
        }
    }

    private void transferEntrustEthErc20(String password, String value, String receiveAddress, String type) {
        {
            EthRpcService.transferEntrustErc20(mActivity, mToken, receiveAddress, value, mGasPrice, getmGasLimit(), password)
                    .subscribe(new CytonSubscriber<EthSendTransaction>() {
                        @Override
                        public void onError(Throwable e) {
                            mTransferView.transferEtherFail(e.getMessage());
                        }

                        @Override
                        public void onNext(EthSendTransaction ethSendTransaction) {
                            if (ethSendTransaction.hasError()) {
                                mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                            } else {
                                mDepositData.setaPendingBalance(NumberUtil.getWeiFromEth(value));

//  mCurrentStep = TYPE_CURRENT_STEP_LOCK;
                                mTransferView.transferEtherSuccess(ethSendTransaction);
                                mDepositData.setStep(TYPE_CURRENT_STEP_LOCK);

                                mActivity.updateLockStatus();
//                                singleLockExec(password, value, receiveAddress, mToken.decimals, type, ethSendTransaction.getTransactionHash());
//                                lock_step2(password, value, receiveAddress, mToken.decimals, type);
                            }
                        }
                    });
        }
    }

    private void transferMCoin(Context context, Token token, String receiveAddress, String mValue, String hValue,
                               BigInteger gasPrice, BigInteger gasLimit, String password, boolean isAppend) {
        EthRpcService.transferEntrustErc20(mActivity, mToken, receiveAddress, mValue, mGasPrice, mGasLimit, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity", "transferMCoin onError:" + e.getMessage());
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                            Log.e("MainActivity", "transferMCoin onNext:" + ethSendTransaction.getError().getMessage());
                        } else {
                            if (isAppend) {
                                mTransferView.transferEtherSuccess(ethSendTransaction);
                                mDepositData.setStep(TYPE_CURRENT_STEP_LOCK);
                                mDepositData.setaPendingBalance(NumberUtil.getWeiFromEth(mValue));
//                                mCurrentStep = TYPE_CURRENT_STEP_LOCK;
//                                mTransferView.transferEtherSuccess(ethSendTransaction);
                                mActivity.updateLockStatus();
//                                lock_mix_append(password, mValue, receiveAddress);
                            } else {
                                transferHCoin(context, mToken1, receiveAddress, hValue, gasPrice, gasLimit, password);
                            }
                        }
                    }
                });
    }


    public void exec_Lock_MixNew(Context context, Token token, String receiveAddress, String value,
                                 BigInteger gasPrice, BigInteger gasLimit, String password) {
        lockMix(context, token, receiveAddress, value, gasPrice, gasLimit, password);
    }

    private void lockMix(Context context, Token token, String receiveAddress, String value,
                         BigInteger gasPrice, BigInteger gasLimit, String password) {
        EthRpcService.
                lockMix(context, token, receiveAddress, value, gasPrice, gasLimit, password)
                .subscribe(new Subscriber<EthSendTransaction>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("MainActivity", "lockMix error:" + (e.getMessage() == null ? "" : e.getMessage()));
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            Log.e("MainActivity", "lockMix error:" + ethSendTransaction.getError().getMessage());
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                            EventBus.getDefault().post(new TransferPushEvent());
                            mActivity.finish();
                        }
                    }
                })
        ;
    }

    private void transferHCoin(Context context, Token token, String receiveAddress, String value,
                               BigInteger gasPrice, BigInteger gasLimit, String password) {
        EthRpcService.transferEntrustErc201(mActivity, mToken1, receiveAddress, value, mGasPrice, getmGasLimit(), password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
//                            mCurrentStep = TYPE_CURRENT_STEP_LOCK;
                            mDepositData.setStep(TYPE_CURRENT_STEP_LOCK);
//                            mTransferView.transferEtherSuccess(ethSendTransaction);
                            mDepositData.setbPendingBalance(NumberUtil.getWeiFromEth(value));
                            mActivity.updateLockStatus();
//                            exec_Lock_MixNew(context, token, receiveAddress, value, gasPrice, gasLimit, password);
                        }
                    }
                });
    }


    public void handleGetBack(Context context, Token token, String receiveAddress, String mValue,
                              String hValue, String password) {
//        mActivity.showProgressBar();
        EthRpcService.claim(context, token, ConstantUtil.getDEPOSITCONTRACT(), mValue, mGasPrice, mGasLimit, password)
                .subscribe(new Subscriber<EthSendTransaction>() {
                    @Override
                    public void onCompleted() {
//                        mActivity.dismissProgressBar();
                    }

                    @Override
                    public void onError(Throwable e) {
//                        mActivity.dismissProgressBar();
                        Toast.makeText(mActivity, R.string.network_error, Toast.LENGTH_SHORT).show();
                        mActivity.transferDialog.dismiss();
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction == null) {
                            Toast.makeText(mActivity, R.string.transfer_fail, Toast.LENGTH_SHORT).show();
                        } else if (ethSendTransaction.getError() != null
                                && !TextUtils.isEmpty(ethSendTransaction.getError().getMessage())) {
                            Toast.makeText(mActivity, ethSendTransaction.getError().getMessage(),
                                    Toast.LENGTH_SHORT).show();
                        } else if (!TextUtils.isEmpty(ethSendTransaction.getTransactionHash())) {
                            Toast.makeText(mActivity, R.string.transfer_success, Toast.LENGTH_SHORT).show();
                            mActivity.transferDialog.dismiss();
                            mActivity.finish();
                        } else {
                            Toast.makeText(mActivity, R.string.transfer_fail, Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    public void handleEntrustMixTransfer(Context context, Token token, String receiveAddress, String mValue,
                                         String hValue, String password) {
        if (mDepositData.isAppend()) {
            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, getmGasLimit(), password, true);
        } else {
            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, getmGasLimit(), password, false);
        }
//        Observable.fromCallable(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                List<Type> datas = ContractService.lockAddress();
//                if (datas != null && datas.size() >= 1) {
//                    return ((Address) datas.get(0)).getValue();
//                }
//                return null;
//            }
//        }).subscribeOn(Schedulers.newThread())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Subscriber<String>() {
//                    @Override
//                    public void onCompleted() {
////                        mTransferView.transferEtherFail("");
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        mTransferView.transferEtherFail(e.getMessage());
//                    }
//
//                    @Override
//                    public void onNext(String s) {
//                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")) {
//                            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, mGasLimit, password, true);
////                            lock_mix_append(password, mValue, s);
//                        } else {
//                            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, mGasLimit, password, false);
//                            //mTransferView.transferEtherFail("获取地址失败");
//                        }
//                    }
//                });

    }

    private void mix_queryDetail() {
        Observable.fromCallable(new Callable<MaxDetailBean>() {
            @Override
            public MaxDetailBean call() throws Exception {

                List<Type> aBalance = ContractService.aTokenBalance();
                if (aBalance != null && aBalance.size() > 0) {
                    BigInteger balance1 = ((Uint256) aBalance.get(0)).getValue();
                    Log.e("MainActivity", "A Balance:" + balance1.toString());
                }

                List<Type> bBalance = ContractService.bTokenBalance();
                if (bBalance != null && bBalance.size() > 0) {
                    BigInteger balance2 = ((Uint256) bBalance.get(0)).getValue();
                    Log.e("MainActivity", "B Balance:" + balance2.toString());
                }


                List<Type> datas = ContractService.queryMixDetail();
                if (datas == null || datas.size() < 3) {
                    return null;
                }
                int rateBase = ((Uint256) datas.get(0)).getValue().intValue();
                int rate = ((Uint256) datas.get(1)).getValue().intValue();
                long unLockTime = ((Uint256) datas.get(2)).getValue().intValue();
                Log.e("MainActivity", "rateBase:" + rateBase + "  rate:" + rate + " unLockTime:" + unLockTime);
                MaxDetailBean bean = new MaxDetailBean();
                bean.setRateM(rate);
                bean.setRateH(rateBase);
                bean.setUnLockTime(unLockTime);

                return bean;
            }
        })
//                .flatMap(new Func1<String, Observable<MaxDetailBean>>() {
//            @Override
//            public Observable<MaxDetailBean> call(String s) {
//                return Observable.fromCallable(new Callable<MaxDetailBean>() {
//                    @Override
//                    public MaxDetailBean call() throws Exception {
//                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")){
//                            return null;
//                        }
//                        List<Type> datas = ContractService.queryMixDetail();
//                        if(datas == null || datas.size() <3){return null;
//                        }
//                        int rateBase = ((Uint256)datas.get(0)).getValue().intValue();
//                        int rate = ((Uint256)datas.get(1)).getValue().intValue();
//                        long unLockTime = ((Uint256)datas.get(2)).getValue().intValue();
//                        MaxDetailBean bean = new MaxDetailBean();
//                        bean.setRate(rate);
//                        bean.setRateBase(rateBase);
//                        bean.setUnLockTime(unLockTime);
//
//                        return bean;
//                    }
//                });
//            }
//        }).
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<MaxDetailBean>() {
                    @Override
                    public void onCompleted() {
                        mActivity.dismissProgressCircle();
//                        mTransferView.transferEtherFail("");
                    }

                    @Override
                    public void onError(Throwable e) {
                        mActivity.dismissProgressCircle();
                        Toast.makeText(mActivity, "查询委托详情失败", Toast.LENGTH_SHORT).show();

                    }

                    @Override
                    public void onNext(MaxDetailBean s) {
                        if (s != null) mBean = s;
                    }
                });
    }

    private void updateGasInfo() {
        if (mGasLimit != null) {
            mGas = mGasPrice.multiply(getmGasLimit());
            mTransferFee = NumberUtil.getEthFromWei(mGas);
            mTransferView.initTransferFeeView();
        }
    }

    /**
     * @param gasPrice wei
     */
    public void updateGasPrice(BigInteger gasPrice) {
        mGasPrice = gasPrice;
        updateGasInfo();
    }

    public void updateGasLimit(BigInteger gasLimit) {
        mGasLimit = gasLimit;
        updateGasInfo();
    }

    public void updateData(String data) {
        mData = data;
    }

    public String getData() {
        return mData;
    }

    public Token getTokenItem() {
        return mToken;
    }

    public Wallet getWalletItem() {
        return mWallet;
    }

    public boolean isTransferFeeEnough() {
        return mNativeTokenBalance - mTransferFee >= 0;
    }

    /**
     * Check whether transfer value is bigger than balance of wallet
     *
     * @return
     */
    public boolean checkTransferValueMoreBalance(String transferValue) {
        if (isNativeToken()) {
            return Double.parseDouble(transferValue) > (mNativeTokenBalance - mTransferFee);
        } else {
            return Double.parseDouble(transferValue) > mTokenBalance;
        }
    }

    public String balanceSubFee() {
        if (isNativeToken()) {
            return NumberUtil.getDecimalValid_8(new BigDecimal(mNativeTokenBalance).subtract(new BigDecimal(mTransferFee)).doubleValue());
        } else {
            return NumberUtil.getDecimalValid_8(mTokenBalance);
        }
    }

    public String getTransferFee() {
        if (mTokenPrice > 0 && EtherUtil.isMainNet()) {
            return NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit()
                    + " ≈ " + mCurrency.getSymbol() + " "
                    + NumberUtil.getDecimalValid_2(mTransferFee * mTokenPrice);
        } else {
            return NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit();
        }
    }

    public BigInteger getGasPrice() {
        return mGasPrice;
    }


    public boolean isNativeToken() {
        return TextUtils.isEmpty(mToken.getContractAddress());
    }

    public boolean isEther() {
        return Numeric.toBigInt(mToken.getChainId()).compareTo(BigInteger.ZERO) < 0;
    }

    public String getFeeTokenUnit() {
        if (EtherUtil.isEther(mToken)) {
            return " " + ConstantUtil.ETH;
        } else {
            Chain chain = DBWalletUtil.getChainItemFromCurrentWallet(mActivity, mToken.getChainId());
            return chain == null || TextUtils.isEmpty(chain.tokenSymbol) ? "" : " " + chain.tokenSymbol;
        }
    }

}
